package com.oa.utils;

import org.activiti.engine.*;
import org.activiti.engine.history.HistoricActivityInstance;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.activiti.engine.task.TaskQuery;

import java.util.List;
import java.util.Map;

/**
 * @Author Str
 * @Date 2021/11/29 21:57
 * @Description :
 */
public class ProcessUtil {

    static ProcessEngine engine;

    static {
        engine = ProcessEngines.getDefaultProcessEngine();
    }

    public static ProcessEngine getEngine() {
        return engine;
    }

    //{1}布署流程方法
    public static Deployment deployProcess(String resName, String procName) {
        ProcessEngine E = getEngine();
        RepositoryService repoSV = E.getRepositoryService();
        Deployment deploy = repoSV.createDeployment()
                .addClasspathResource("processes/" + resName + ".bpmn")
                .addClasspathResource("processes/" + resName + ".png")
                .name(procName)
                .deploy();
        prtMark("布署流程成功:" + deploy.getId());

        return deploy;
    }

    // 获取流程定义ID
    public static String getProcessDefinitionID(String deployID) {
        // 获取流程定义ID
        String proDefId = getEngine().getRepositoryService().createProcessDefinitionQuery().deploymentId(deployID).singleResult().getId();
        prtMark("流程定义ID：" + proDefId);
        return proDefId;
    }

    //{2}删除流程定义
    public static void deleteProcessByDeployID(
            String deployID, boolean isCascade) {
        ProcessEngine E = getEngine();
        RepositoryService repoSV = E.getRepositoryService();
        // true代表级联删除
        repoSV.deleteDeployment(deployID, isCascade);
        prtMark("删除流程成功:" + deployID);
    }


    //{3}查询流程定义列表
    public static void findProcessDefinition() {
        List<ProcessDefinition> list = getEngine().getRepositoryService()//与流程定义和部署对象相关的Service
                .createProcessDefinitionQuery()//创建一个流程定义查询
                /*指定查询条件,where条件*/
                //.deploymentId(deploymentId)//使用部署对象ID查询
                //.processDefinitionId(processDefinitionId)//使用流程定义ID查询
                //.processDefinitionKey(processDefinitionKey)//使用流程定义的KEY查询
                //.processDefinitionNameLike(processDefinitionNameLike)//使用流程定义的名称模糊查询

                /*排序*/
                .orderByProcessDefinitionVersion().asc()//按照版本的升序排列
                //.orderByProcessDefinitionName().desc()//按照流程定义的名称降序排列

                .list();//返回一个集合列表，封装流程定义
        //.singleResult();//返回唯一结果集
        //.count();//返回结果集数量
        //.listPage(firstResult, maxResults)//分页查询

        if (list != null && list.size() > 0) {
            for (ProcessDefinition processDefinition : list) {
                System.out.println("流程定义ID:" + processDefinition.getId());//流程定义的key+版本+随机生成数
                System.out.println("流程定义名称:" + processDefinition.getName());//对应HelloWorld.bpmn文件中的name属性值
                System.out.println("流程定义的key:" + processDefinition.getKey());//对应HelloWorld.bpmn文件中的id属性值
                System.out.println("流程定义的版本:" + processDefinition.getVersion());//当流程定义的key值相同的情况下，版本升级，默认从1开始
                System.out.println("资源名称bpmn文件:" + processDefinition.getResourceName());
                System.out.println("资源名称png文件:" + processDefinition.getDiagramResourceName());
                System.out.println("部署对象ID:" + processDefinition.getDeploymentId());
                System.out.println("################################");
            }
        }

    }


    //{4}开启流程实例 (备注: 传入流程定义 ID)
    public static void startInstanceById(
            String procDefID, Map<String, Object> data) {
        //{1}获取运行时相关的服务对象。
        RuntimeService rtService = getEngine().getRuntimeService();
        //{2}获取运行时相关的服务对象。
        ProcessInstance ins = rtService.startProcessInstanceById(
                procDefID, data);
        prtMark("开启流程实例成功:" + ins.getId());
    }

    //{5}查询某个办理人的所有任务
    static String LINE = "+---------------------------" +
            "----------------------------+\n";
    static String TASK_TI = "| 任务ID | 当前办理人 | 任务名称 | 任务描述 | 创建日期 |\n";

    public static List<Task> getTaskByAssingee(
            String assingee, String procDefID) {
        TaskService taskService = getEngine().getTaskService();

        TaskQuery qry = taskService.createTaskQuery();
        //{1}设置一个查询条件: 办理人
        if (assingee != null) {
            qry.taskAssignee(assingee);
        }
        //{2}如果这个 ID 不为 null, 再设置一个查询 ID 条件
        if (procDefID != null) {
            qry.processDefinitionId(procDefID);
        }
        //{3}查询出结果。
        List<Task> list = qry.list();
        System.out.print(LINE);
        System.out.print(TASK_TI);
        System.out.print(LINE);
        for (Task task : list) {
            System.out.printf("%s, %s, %s, %s, %s\n",
                    task.getId(), task.getAssignee(),
                    task.getName(), task.getDescription(),
                    task.getCreateTime().toLocaleString());
        }
        return list;
    }

    //{6}办理某个任务
    public static void completeTask(
            String taskId, Map<String, Object> data) {
        //{1}data: 流程变量 (在流程中传递的数据)
        getEngine().getTaskService()
                .complete(taskId, data);
    }

    //{7}获取某个流程实例的流程变量
    public static Map<String, Object> getProcValiables(
            String taskID) {
        return getEngine().getTaskService()
                .getVariables(taskID);
    }

    //{8}获取某个流程实例的其中一个流程变量
    public static Object getProcOneValiable(
            String taskID, String KEY) {
        return getEngine().getTaskService()
                .getVariable(taskID, KEY);
    }


    //{7}查询 "历史活动" 信息
    public static List<HistoricActivityInstance>
    getActivityHistory(String procInsID) {
        //{1}获取一个与历史数据有关的服务。
        HistoryService hisService = getEngine()
                .getHistoryService();
        List<HistoricActivityInstance> list = null;
        list = hisService.createHistoricActivityInstanceQuery()
                .processInstanceId(procInsID)
                .list();
        return list;
    }

    //{8}查询 "历史任务" 信息
    public static List<HistoricTaskInstance>
    getTaskHistory(String procInsID) {
        //{1}获取一个与历史数据有关的服务。
        HistoryService hisService = getEngine()
                .getHistoryService();
        List<HistoricTaskInstance> list = null;
        list = hisService.createHistoricTaskInstanceQuery()
                .processInstanceId(procInsID)
                .list();
        return list;
    }

    private static void prtMark(Object obj) {
        System.out.println("+------------------------------------------------+");
        System.out.print("\n");
        System.out.print(obj);
        System.out.print("\n");
        System.out.println("+------------------------------------------------+");
    }

}